//
//  MZCollectionViewCell.swift
//  MZTool
//
//  Created by gby on 2023/4/24.
//

import UIKit

public class MZFlowLayout_FilmCard: UICollectionViewFlowLayout {
    
    public var maxScale: CGFloat = 0.5
    
    public override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let sup_attributes = super.layoutAttributesForElements(in: rect)
        let ary = self.getCopyOfAttributes(attributes: sup_attributes)
        if let collview = self.collectionView {
            let centerX:CGFloat = collview.contentOffset.x + collview.bounds.width/2
            for attribute in ary {
                let distance: CGFloat = abs(attribute.center.x - centerX)
                let apartScale: CGFloat = 1 - min(1, distance/(self.itemSize.width + self.minimumLineSpacing))
                let scale = 1 + maxScale * apartScale
                attribute.transform3D = CATransform3DMakeScale(scale, scale, 1)
                let scaleHeight = attribute.frame.size.height * scale
                let offsetY = max(0, scaleHeight/2 - attribute.frame.size.height/2)
                let center = CGPoint.init(x: attribute.center.x, y: collview.center.y - offsetY)
                attribute.center = center
            }
        }
        return ary
    }
    
    public override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
    
    func getCopyOfAttributes(attributes: [UICollectionViewLayoutAttributes]?) -> [UICollectionViewLayoutAttributes]{
        var cpy: [UICollectionViewLayoutAttributes] = []
        for attribute in attributes ?? [] {
            if let a = attribute.copy() as? UICollectionViewLayoutAttributes{
                cpy.append(a)
            }
        }
        return cpy
    }
    
    public override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        if self.collectionView?.isPagingEnabled ?? false {
            return proposedContentOffset
        }
        guard let collview = self.collectionView else{
            return proposedContentOffset
        }
        
        var _proposedContentOffset = proposedContentOffset
        var offsetAdjustment: CGFloat = CGFloat(MAXFLOAT)
        let horizontalCenter: CGFloat = proposedContentOffset.x + collview.frame.size.width * 0.5
        
        let targetRect = CGRect.init(x: proposedContentOffset.x, y: 0, width: collview.bounds.size.width, height: collview.bounds.size.height)
        
        let attributes = self.layoutAttributesForElements(in: targetRect)
        let cellattributes = attributes?.filter({ layoutattributes in
            return layoutattributes.representedElementCategory == .cell
        })
        
        var currentattributes: UICollectionViewLayoutAttributes?
        for layoutattributes in cellattributes ?? [] {
            let itemHorizontalCenter: CGFloat = layoutattributes.center.x
            if abs(itemHorizontalCenter - horizontalCenter) < abs(offsetAdjustment) {
                currentattributes = layoutattributes
                offsetAdjustment = itemHorizontalCenter - horizontalCenter
            }
        }
        
        let nextOffset = proposedContentOffset.x + offsetAdjustment
        
        _proposedContentOffset.x = nextOffset
        let deltaX: CGFloat = proposedContentOffset.x - collview.contentOffset.x
        let velX: CGFloat = velocity.x
        
        if abs(deltaX) <= CGFloat(Float.ulpOfOne) || abs(velX) <= CGFloat(Float.ulpOfOne) || (velX > 0.0 && deltaX > 0.0) || (velX < 0.0 && deltaX < 0.0){
            
        }else{
            var proposeX: CGFloat = 0.0
            for layoutattributes in attributes ?? []{
                if layoutattributes.representedElementCategory == .cell{
                    let itemHorizontalCenter: CGFloat = layoutattributes.center.x
                    if itemHorizontalCenter < proposedContentOffset.x {
                        proposeX = nextOffset + (currentattributes?.frame.size.width ?? 0)/2 - layoutattributes.frame.size.width/2
                    }else{
                        proposeX = nextOffset - (currentattributes?.frame.size.width ?? 0)/2 + layoutattributes.frame.size.width/2
                    }
                }
            }
            _proposedContentOffset.x = proposeX
        }
        _proposedContentOffset.y = 0.0
        
        return _proposedContentOffset
    }
}
